package com.swak.fx.support.ability;

import java.io.Serializable;
import java.util.function.Supplier;

import com.swak.fx.support.ui.UI;

import javafx.geometry.Bounds;
import javafx.scene.Node;
import javafx.scene.SnapshotParameters;
import javafx.scene.image.WritableImage;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

/**
 * 可拖动
 * 
 * @author 618lf
 */
@Getter
@Setter
@Accessors(chain = true)
public class DragAbleAbility {

	final Node dragAble;
	final Supplier<Serializable> param;

	public DragAbleAbility(Node dragAble, Supplier<Serializable> param) {
		this.dragAble = dragAble;
		this.param = param;
		this.init();
	}

	private void init() {
		this.dragAble.setOnDragDetected(e -> {
			Dragboard dragboard = this.dragAble.startDragAndDrop(TransferMode.COPY);
			ClipboardContent clipboardContent = new ClipboardContent();
			clipboardContent.put(UI.ClipboardDataFormat.OBJECT, this.param.get());
			dragboard.setContent(clipboardContent);

			SnapshotParameters parameters = new SnapshotParameters();
			WritableImage snapshot = this.dragAble.snapshot(parameters, null);
			Bounds bounds = this.dragAble.localToScreen(this.dragAble.getBoundsInLocal());
			double offsetX = bounds.getMinX() - e.getScreenX();
			double offsetY = bounds.getMinY() - e.getScreenY();
			dragboard.setDragView(snapshot, -offsetX, -offsetY);
		});
	}

	public static DragAbleAbility of(Node dragAble, Supplier<Serializable> param) {
		return new DragAbleAbility(dragAble, param);
	}
}
